package com.taiji.dianthus.service.sys.impl;


import com.alibaba.fastjson.JSONArray;
import com.taiji.dianthus.common.BusinessMessage;
import com.taiji.dianthus.dao.sys.UserRepository;
import com.taiji.dianthus.domain.sys.DSysMenu;
import com.taiji.dianthus.domain.sys.DSysOrg;
import com.taiji.dianthus.domain.sys.DSysRole;
import com.taiji.dianthus.domain.sys.DSysUser;
import com.taiji.dianthus.dto.UserDto;
import com.taiji.dianthus.service.sys.OrgService;
import com.taiji.dianthus.service.sys.RoleUserService;
import com.taiji.dianthus.service.sys.UserService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.taiji.dianthus.common.Constant.DEFAULT_PASSWORD;


/**
 * @ClassName UserServiceImpl
 * @Description
 * @Author H.M
 * @Date 2019/9/27
 */
@Service("DSysUser")
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {

    Log log = LogFactory.getLog(UserServiceImpl.class);

    @Value("${user_role}")
    private String originUserRole;//普通用户

    @Autowired
    private UserRepository repository;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private RoleUserService roleUserService;
    @Autowired
    private OrgService orgService;


    /**
     * 获取用户名
     *
     * @param userCode
     * @return
     */
    @Override
    public String getNameByCode(String userCode) {
        return repository.getById(userCode).getName();
    }

    /**
     * @param loginName
     * @return
     */
    @Override
    public DSysUser findByLoginName(String loginName) {
        return repository.findByLoginName(loginName);
    }

    /**
     * @param name
     * @param useLoginName
     * @param userPassword
     * @param userMail
     * @param userPhone
     * @param orgId
     * @param lastLoginTime
     * @return
     */
    @Override
    public BusinessMessage add(String name, String useLoginName, String userPassword, String userMail, String userPhone, String orgId, String lastLoginTime) {
        return add(null, name, useLoginName, userPassword, userMail, userPhone, orgId, lastLoginTime, null);
    }

    /**
     * @param name
     * @param useLoginName
     * @param userPassword
     * @param userMail
     * @param orgId
     * @param lastLoginTime
     * @return
     */
    @Override
    public BusinessMessage add(String id, String name, String useLoginName, String userPassword,
                               String userMail, String userPhone, String orgId, String lastLoginTime,
                               String roleId) {
        BusinessMessage message = new BusinessMessage();
        try {
            DSysUser dSysUser = new DSysUser();
            dSysUser.setName(name);
            if (null != id) {
                dSysUser = repository.getById(id);
            }
            dSysUser.setUserLoginName(useLoginName);
            if (StringUtils.isEmpty(userPassword)) {
                dSysUser.setUserPassword(passwordEncoder.encode(DEFAULT_PASSWORD));
            } else {
                dSysUser.setUserPassword(userPassword);
            }
            dSysUser.setUserMail(userMail);
            dSysUser.setUserPhone(userPhone);
            dSysUser.setOrgId(orgId);
            dSysUser.setLastLoginTime(lastLoginTime);
            dSysUser = repository.save(dSysUser);
            message.setData(dSysUser);
            message.setMsg("新建/用户成功");
            message.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("新建/用户失败");
        }
        return message;
    }

    /**
     * 用户新增、编辑
     *
     * @param userDto
     * @return
     */
    @Override
    public BusinessMessage add(UserDto userDto) {
        BusinessMessage message = new BusinessMessage();
        try {
            DSysUser dSysUser = new DSysUser();
            String userId = userDto.getId();
            BeanUtils.copyProperties(userDto, dSysUser);
            if (StringUtils.isEmpty(userId)) {
                dSysUser.setUserPassword(passwordEncoder.encode(DEFAULT_PASSWORD));
            }
            dSysUser = repository.save(dSysUser);
            //用户角色变更
            if (null == userId) {
                //新建用户
                roleUserService.save(dSysUser.getId(), userDto.getRoleId());
            } else {
                //查询原有用户角色
                String roleId = roleUserService.getByUser(userId);
                if (null == roleId) {
                    roleUserService.save(userDto.getRoleId(), userId);
                } else {
                    //如果角色id没有变化 不更新
                    if (roleId.equals(userDto.getRoleId())) {

                    } else {
                        roleUserService.update(userId, userDto.getRoleId());
                    }
                }

            }
            message.setData(dSysUser);
            message.setMsg("新建/编辑用户成功");
            message.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("系统异常");
        } finally {
            return message;
        }
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public BusinessMessage delete(String id) {
        BusinessMessage message = new BusinessMessage();
        try {
            repository.updateFlag(id);
            message.setSuccess(true);
            message.setMsg("删除用户成功");
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("删除用户失败");
        }
        return message;
    }

    /**
     * 根据用户唯一码获取菜单 TODO
     *
     * @param userCode
     * @return
     */
    @Override
    public List<DSysMenu> listMenuByUser(String userCode) {
        Set<DSysRole> roleSet = roleUserService.listByUser(userCode);
        return null;
    }

    /**
     * 获取列表
     *
     * @param currentPage
     * @param pageSize
     * @return
     */
    @Override
    public BusinessMessage list(Integer currentPage, Integer pageSize) {
        return list(currentPage, pageSize, null, null);
    }

    @Override
    public BusinessMessage list(Integer currentPage, Integer pageSize, String userName,
                                String phone) {
        BusinessMessage message = new BusinessMessage();
        try {
            Sort sort = new Sort(Sort.Direction.DESC, "createTime");
            //分页参数
            Pageable pageable = PageRequest.of(currentPage, pageSize, sort);
            Page<DSysUser> userPage;
            Specification<DSysUser> spec = (Root<DSysUser> root, CriteriaQuery<?> query, CriteriaBuilder cb) -> {
                List<Predicate> pl = new ArrayList<Predicate>();
                if (!StringUtils.isEmpty(userName)) {
                    pl.add(cb.like(root.<String>get("name"), userName + "%"));
                }
                if (!StringUtils.isEmpty(phone)) {
                    pl.add(cb.like(root.<String>get("userPhone"), phone + "%"));
                }
                //查询未删除的
                pl.add(cb.equal(root.<Integer>get("enableFlag"), 1));
                return cb.and(pl.toArray(new Predicate[0]));
            };
            userPage = repository.findAll(spec, pageable);
            message.setMsg("查询用户列表成功");
            message.setData(userPage);
            message.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("查询用户列表失败");
        }

        return message;
    }

    /**
     * 根据ID 获取
     *
     * @param id
     * @return
     */
    @Override
    public DSysUser getById(String id) {
        return repository.getById(id);
    }

    /**
     * 根据登录名查询数量
     *
     * @param loginName
     * @return
     */
    @Override
    public Integer countByLoginName(String loginName) {
        return repository.countByLoginName(loginName);
    }

    /**
     * 查询所有有组织的用户
     *
     * @return
     */
    @Override
    public List<DSysUser> listUserHasOrg() {
        return repository.listUserWithOrg();
    }

    /**
     * 根据id集合查询用户集
     *
     * @param ids
     * @return
     */
    @Override
    public List<DSysUser> listByIds(List<String> ids) {
        return repository.listByIds(ids);
    }

    /**
     * 修改用户密码
     *
     * @param userId
     * @param password
     */
    @Override
    public BusinessMessage updatePassword(String userId, String password) {
        BusinessMessage message = new BusinessMessage();
        try {
            password = passwordEncoder.encode(password);
            DSysUser user = repository.getById(userId);
            user.setUserPassword(password);
            repository.saveAndFlush(user);
            message.setMsg("修改成功");
            message.setSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            message.setMsg("系统异常");
        }
        return message;
    }

    /**
     * 查询用户总数
     *
     * @return
     */
    @Override
    public Integer countUser() {
        return repository.countUser();
    }

    @Override
    public List<DSysUser> getUserByRoleId(String id) {
        return repository.getUserByRoleId(id);
    }

    @Override
    public DSysUser getByPushId(String pushId) {
        return repository.getByPushId(pushId);
    }

    @Override
    public DSysUser save(DSysUser user) {
        return repository.saveAndFlush(user);
    }

    @Override
    public Integer countPushId(String pushId) {
        return repository.countPushId(pushId);
    }

    @Override
    public List<DSysUser> getByOrgId(String id) {
        return repository.getByOrgId(id);
    }

    @Override
    public Map<String, Object> getUserByPhone(String mobile) {
        return repository.getUserByPhone(mobile);
    }

    @Override
    public List<BusinessMessage> addSynBaseUser(String jsonArrayStr) {
        log.info("---------------调用新增用户方法 START ---------------------");
        List<BusinessMessage> messageList = new ArrayList<>();
        try {
            jsonArrayStr = new String(jsonArrayStr.getBytes("UTF-8"), "UTF-8");
            List<Map<String, Object>> mapList = JSONArray.parseObject(jsonArrayStr, List.class);
            if (null != mapList && mapList.size() > 0) {
                for (Map<String, Object> map : mapList) {
                    String orgId = (String) map.get("orgId");
                    String pushId = (String) map.get("id");
                    DSysOrg org = orgService.getOrgByPushId(orgId);//查询当前部门信息
                    Integer count = repository.countPushId(pushId);
                    BusinessMessage message = new BusinessMessage();
                    if (org == null) {
                        message.setMsg("增加用户的组织不存在");
                        message.setCode("402");
                        message.setData(pushId);
                        messageList.add(message);
                    } else if (count > 0) {
                        message.setMsg("增加用户唯一标识重复");
                        message.setCode("401");
                        message.setData(pushId);
                        messageList.add(message);
                    } else {
                        log.info("**************新增用户 START*************");
                        DSysUser user = new DSysUser();
                        user.setPushId(pushId);
                        user.setName((String) map.get("name"));
                        user.setOrgId(org.getId());
                        user.setUserLoginName((String) map.get("userLoginName"));
                        user.setEnableFlag((Integer) map.get("enableFlag"));
                        user.setUserPassword((String) map.get("userPassword"));
                        user.setUserPhone((String) map.get("userPhone"));
                        user.setUserOrder((Integer) map.get("userOrder"));
                        user.setUserMail((String) map.get("userMail"));
                        user.setUserDuty((String) map.get("userDuty"));
                        user.setUserPosition((String) map.get("userPosition"));
                        user.setUserSex((String) map.get("userSex"));
                        user = repository.save(user);
                        log.info("**************新增用户角色 START*************");
                            /*DSysUserRole userRole = new DSysUserRole();
                            userRole.setUserCode(user.getId());
                            userRole.setRoleId(originUserRole);*/
                        roleUserService.save(originUserRole, user.getId());
                        log.info("************新增用户角色 END***************");
                    }
                    log.info("************新增用户 END***************");
                }
            } else {
                BusinessMessage message = new BusinessMessage();
                message.setCode("1003");
                message.setMsg("推送的数据为空");
                messageList.add(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
            BusinessMessage message = new BusinessMessage();
            message.setCode("1002");
            message.setMsg("用户新增失败，系统异常");
            messageList.add(message);

        } finally {
            log.info("---------------调用新增用户方法 END ---------------------");
            return messageList;
        }
    }

    @Override
    public List<BusinessMessage> updateSynBaseUser(String jsonArrayStr) {
        log.info("---------------调用更新用户方法 START ---------------------");
        List<BusinessMessage> messageList = new ArrayList<>();
        try {
            jsonArrayStr = new String(jsonArrayStr.getBytes("UTF-8"), "UTF-8");
            List<Map<String, Object>> mapList = JSONArray.parseObject(jsonArrayStr, List.class);
            if (null != mapList && mapList.size() > 0) {
                for (Map<String, Object> map : mapList) {
                    log.info("***********更新用户 START ****************");
                    String orgId = (String) map.get("orgId");
                    String pushId = (String) map.get("id");
                    DSysOrg org = orgService.getOrgByPushId(orgId);
                    DSysUser user = repository.getByPushId(pushId);
                    BusinessMessage message = new BusinessMessage();
                    if (user == null) {
                        message.setMsg("编辑的用户不存在");
                        message.setCode("501");
                        message.setData(pushId);
                        messageList.add(message);
                    } else if (org == null) {
                        message.setMsg("编辑的用户的组织不存在");
                        message.setCode("502");
                        message.setData(pushId);
                        messageList.add(message);
                    } else {
                        user.setName((String) map.get("name"));
                        user.setOrgId(org.getId());
                        user.setUserPassword((String) map.get("userPassword"));
                        user.setUserLoginName((String) map.get("userLoginName"));
                        user.setEnableFlag((Integer) map.get("enableFlag"));
                        user.setUserPhone((String) map.get("userPhone"));
                        user.setUserOrder((Integer) map.get("userOrder"));
                        user.setUserMail((String) map.get("userMail"));
                        user.setUserDuty((String) map.get("userDuty"));
                        user.setUserPosition((String) map.get("userPosition"));
                        user.setUserSex((String) map.get("userSex"));
                        repository.save(user);
                    }
                    log.info("***********更新用户 END****************");
                }
            } else {
                BusinessMessage message = new BusinessMessage();
                message.setCode("1003");
                message.setMsg("推送的数据为空");
                messageList.add(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
            BusinessMessage message = new BusinessMessage();
            message.setCode("1002");
            message.setMsg("用户更新失败，系统异常");
            messageList.add(message);
        } finally {
            log.info("---------------用户更新组织方法 END ---------------------");
            return messageList;
        }
    }

    @Override
    public List<BusinessMessage> deleteSynBaseUser(String jsonArrayStr) {
        log.info("---------------调用删除用户方法 START ---------------------");
        List<BusinessMessage> messageList = new ArrayList<>();
        try {
            jsonArrayStr = new String(jsonArrayStr.getBytes("UTF-8"), "UTF-8");
            List<Map<String, Object>> mapList = JSONArray.parseObject(jsonArrayStr, List.class);
            if (null != mapList && mapList.size() > 0) {
                for (Map<String, Object> map : mapList) {
                    log.info("***********删除用户信息 START ****************");
                    String pushId = (String) map.get("id");
                    DSysUser user = repository.getByPushId(pushId);
                    BusinessMessage message = new BusinessMessage();
                    if (user == null) {
                        message.setMsg("删除的用户不存在");
                        message.setCode("601");
                        message.setData(pushId);
                        messageList.add(message);
                    } else {
                        repository.updateFlag(user.getId());
                        roleUserService.deleteByUserId(user.getId());
                    }
                    log.info("***********删除用户信息 END ****************");
                }
            } else {
                BusinessMessage message = new BusinessMessage();
                message.setCode("1003");
                message.setMsg("用户删除失败,推送的数据为空");
                messageList.add(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
            BusinessMessage message = new BusinessMessage();
            message.setCode("1002");
            message.setMsg("用户删除失败，系统异常");
            messageList.add(message);
        } finally {
            log.info("---------------调用删除用户方法 END ---------------------");
            return messageList;
        }
    }

}
